/*
 * This file is part of the eccOS Library.
 * Copyright (C) 2007.
 *
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 */
package org.openeccos.model;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.Hibernate;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.openeccos.dao.EccosRepository;
import org.openeccos.util.ServerUtil;

import com.sas.framework.expojo.ModelExposer;

/**
 *
 * @author cgspinner@web.de
 */
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "t_eccos_user")
public class MUser extends MDefaultEccleEntry {

	protected String firstName;
	protected String lastName;
	protected String street;
	protected String zipCode;
	protected String city;
	protected String fax;
	protected String phone;
	protected String mobile;
	protected String email;
	protected String login;
	protected String invitationCode;
	protected String password;
	protected Calendar lastInvitationDate;
	protected boolean active = true;
	protected Locale locale = Locale.GERMAN;
	protected List<MUserRole> roles = new ArrayList<MUserRole>();

	public MUser() {
		// Empty
	}

	@Column(columnDefinition = "INTEGER")
	public boolean isActive() {
		return active;
	}

	public void setActive(boolean active) {
		this.active = active;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getStreet() {
		return street;
	}

	public void setStreet(String street) {
		this.street = street;
	}

	public String getZipCode() {
		return zipCode;
	}

	public void setZipCode(String zipCode) {
		this.zipCode = zipCode;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	@Transient
	public Locale getLocale() {
		return locale;
	}

	public void setLocale(Locale locale) {
		this.locale = locale;
	}

	public String getLogin() {
		return login;
	}

	public void setLogin(String login) {
		this.login = login;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@Override
	public String toString() {
		if (!ServerUtil.isEmpty(login)) {
			return login;
		}
		if (!ServerUtil.isEmpty(lastName) || !ServerUtil.isEmpty(firstName)) {
			return lastName + ", " + firstName;
		}
		return null;
	}

//	@Column(columnDefinition = "INTEGER")
//	public boolean isInvited() {
//		return invited;
//	}
//
//	public void setInvited(boolean invited) {
//		this.invited = invited;
//	}

	public Calendar getLastInvitationDate() {
		return lastInvitationDate;
	}

	public void setLastInvitationDate(Calendar lastInvitationDate) {
		this.lastInvitationDate = lastInvitationDate;
	}

//	@Transient
//	public String getLastInvitationDateStr() {
//		if (lastInvitationDate != null) {
//			return PDFormat.getDefaultDateOnlyFormat().format(lastInvitationDate.getTime());
//		}
//		return null;
//	}

	@OneToMany(mappedBy = "userRef")
	@LazyCollection(LazyCollectionOption.EXTRA)
	@Cascade( { org.hibernate.annotations.CascadeType.ALL, org.hibernate.annotations.CascadeType.EVICT })
	public List<MUserRole> getRoles() {
		return roles;
	}

	public void setRoles(List<MUserRole> roles) {
		this.roles = roles;
	}

	public MUserRole addRole(MRole role) {
		MUserRole ur = new MUserRole();
		ur.setRole(role);
		ur.setUserRef(this);
		roles.add(ur);
		return ur;
	}

	public String getFax() {
		return fax;
	}

	public void setFax(String fax) {
		this.fax = fax;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}


	public boolean hasRole(IRoleName roleName) {
		if (roleName == null) {
			return false;
		}
		if (Hibernate.isInitialized(getRoles())) {
			for (MUserRole ur : getRoles()) {
				if (roleName.toString().equals(ur.getRole().getName())) {
					return true;
				}
			}
			return false;
		} else {
			//roles are *not* loaded, make a dynamic lookup
			EccosRepository repo = (EccosRepository)ModelExposer.get().getRepository(EccosRepository.NAME);
			return repo.hasRole(this, roleName);
		}
	}

	public boolean hasPrivilege(IPrivilegeName privilegeName) {
		if (privilegeName == null) {
			return false;
		}
		//all dependant collections must have been initialized! - otherwise this won't work
		for (MUserRole ur : getRoles()) {
			for (MRolePrivilege rp : ur.getRole().getPrivileges()) {
				if (privilegeName.toString().equals(rp.getPrivilegeName())) {
					return true;
				}
			}
		}
		return false;
	}


	@Transient
	public String getCompleteName() {
		if (!ServerUtil.isEmpty(firstName) && !ServerUtil.isEmpty(lastName)) {
			return firstName + " " + lastName;
		} else if (!ServerUtil.isEmpty(firstName) && ServerUtil.isEmpty(lastName)) {
			return lastName;
		} else if (ServerUtil.isEmpty(firstName) && !ServerUtil.isEmpty(lastName)) {
			return firstName;
		}
		return null;
	}

	@Override
	public void updateCachedTitle() {
		cachedTitle = toString();
	}

	public String getInvitationCode() {
		return invitationCode;
	}

	public void setInvitationCode(String invitationCode) {
		this.invitationCode = invitationCode;
	}

	public String getMobile() {
		return mobile;
	}

	public void setMobile(String mobile) {
		this.mobile = mobile;
	}
}